package com.viknix.threadpool.manager.server.dependence.factory;

import com.viknix.threadpool.manager.server.dependence.executor.ThreadPoolManager;

import java.util.concurrent.*;

/**
 * @Author: Dongqi
 * @Date: 2021/11/11 18:29
 * @Version 1.0
 * @Description: 统一线程池创建工厂，通过ThreadPoolManager统一生命周期管理
 */
@SuppressWarnings({"PMD.ThreadPoolCreationRule", "checkstyle:overloadmethodsdeclarationorder",
        "checkstyle:missingjavadocmethod"})
public class ExecutorFactory {

    /**
     * 构建只有一个线程的线程池对象（核心线程和最大线程数都为1）
     *
     * @param threadFactory 线程工厂
     * @return 只有一个线程的线程池
     */
    public static ExecutorService newSingleExecutorService(final ThreadFactory threadFactory) {
        return Executors.newFixedThreadPool(1, threadFactory);
    }

    /**
     * 构建只有一个核心线程，最大线程数为 Integer.MAX_VALUE 的定时线程池
     *
     * @param threadFactory 线程池工厂
     * @return 只有一个核心线程，最大线程数为 Integer.MAX_VALUE 的定时线程池
     */
    public static ScheduledExecutorService newSingleScheduledExecutorService(final ThreadFactory threadFactory) {
        return Executors.newScheduledThreadPool(1, threadFactory);
    }

    /**
     * 通过 Managed 构建的线程池对象会交给资源管理器管理器管理其生命周期
     */
    public static final class Managed {

        /**
         * 注册到资源管理器中的命名空间
         */
        private static final String DEFAULT_NAMESPACE = "tpm";

        /**
         * 线程池资源管理器
         */
        private static final ThreadPoolManager THREAD_POOL_MANAGER = ThreadPoolManager.getInstance();

        /**
         * 构建只有一个线程的线程池对象（核心线程和最大线程数都为1），并交给资源管理器管理
         *
         * @param group 资源管理器分组
         * @return 单线程线程池
         */
        public static ExecutorService newSingleExecutorService(final String group) {
            ExecutorService executorService = Executors.newFixedThreadPool(1);
            THREAD_POOL_MANAGER.register(DEFAULT_NAMESPACE, group, executorService);
            return executorService;
        }

        /**
         * 构建只有一个线程的线程池对象（核心线程和最大线程数都为1），并交给资源管理器管理
         *
         * @param group         资源管理器分组
         * @param threadFactory 线程工厂
         * @return 单线程线程池
         */
        public static ExecutorService newSingleExecutorService(final String group, final ThreadFactory threadFactory) {
            ExecutorService executorService = Executors.newFixedThreadPool(1, threadFactory);
            THREAD_POOL_MANAGER.register(DEFAULT_NAMESPACE, group, executorService);
            return executorService;
        }

        /**
         * 构建固定线程的线程池对象，并交给资源管理器管理
         *
         * @param group    资源管理器分组
         * @param nThreads 固定线程数
         * @return 固定线程的线程池对象
         */
        public static ExecutorService newFixedExecutorService(final String group, final int nThreads) {
            ExecutorService executorService = Executors.newFixedThreadPool(nThreads);
            THREAD_POOL_MANAGER.register(DEFAULT_NAMESPACE, group, executorService);
            return executorService;
        }

        /**
         * 构建固定线程的线程池对象，并交给资源管理器管理
         *
         * @param group         资源管理器分组
         * @param nThreads      固定线程数
         * @param threadFactory 线程工厂
         * @return 固定线程的线程池对象
         */
        public static ExecutorService newFixedExecutorService(final String group, final int nThreads,
                                                              final ThreadFactory threadFactory) {
            ExecutorService executorService = Executors.newFixedThreadPool(nThreads, threadFactory);
            THREAD_POOL_MANAGER.register(DEFAULT_NAMESPACE, group, executorService);
            return executorService;
        }

        /**
         * 构建只有一个核心线程，最大线程数为 Integer.MAX_VALUE 的定时线程池，并交给资源管理器管理
         *
         * @param group         资源管理器分组
         * @param threadFactory 线程工厂
         * @return 只有一个核心线程，最大线程数为 Integer.MAX_VALUE 的定时线程池
         */
        public static ScheduledExecutorService newSingleScheduledExecutorService(final String group,
                                                                                 final ThreadFactory threadFactory) {
            ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1, threadFactory);
            THREAD_POOL_MANAGER.register(DEFAULT_NAMESPACE, group, executorService);
            return executorService;
        }

        /**
         * 构建指定核心线程，最大线程数为 Integer.MAX_VALUE 的定时线程池，并交给资源管理器管理
         *
         * @param group         资源管理器分组
         * @param nThreads      核心线程数
         * @param threadFactory 线程工厂
         * @return 指定核心线程，最大线程数为 Integer.MAX_VALUE 的定时线程池
         */
        public static ScheduledExecutorService newScheduledExecutorService(final String group, final int nThreads,
                                                                           final ThreadFactory threadFactory) {
            ScheduledExecutorService executorService = Executors.newScheduledThreadPool(nThreads, threadFactory);
            THREAD_POOL_MANAGER.register(DEFAULT_NAMESPACE, group, executorService);
            return executorService;
        }

        /**
         * 构建一个自定义的线程池，并交给资源管理器管理
         *
         * @param group           资源管理器分组
         * @param coreThreads     核心线程数
         * @param maxThreads      最大线程数
         * @param keepAliveTimeMs 线程存活时间
         * @param threadFactory   线程工厂
         * @return 自定义线程池
         */
        public static ThreadPoolExecutor newCustomerThreadExecutor(final String group, final int coreThreads,
                                                                   final int maxThreads, final long keepAliveTimeMs, final ThreadFactory threadFactory) {
            ThreadPoolExecutor executor = new ThreadPoolExecutor(coreThreads, maxThreads, keepAliveTimeMs,
                    TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), threadFactory);
            THREAD_POOL_MANAGER.register(DEFAULT_NAMESPACE, group, executor);
            return executor;
        }
    }
}
